package com.codi.api.controller.h5;

import com.codi.api.validation.AccountValidation;
import com.codi.base.config.ConfigurationMgr;
import com.codi.base.domain.BaseResult;
import com.codi.base.log.annotation.Loggable;
import com.codi.base.util.RandomUtil;
import com.codi.base.util.StringUtil;
import com.codi.base.web.RequestUtils;
import com.codi.base.web.ResponseUtils;
import com.codi.bus.constant.GlobalConstant;
import com.codi.bus.core.domain.User;
import com.codi.bus.core.domain.UserBank;
import com.codi.bus.core.resultModel.AccountOpenResult;
import com.codi.bus.core.resultModel.CardBinResult;
import com.codi.bus.core.resultModel.PaySignResult;
import com.codi.bus.core.resultModel.PayableBankListResult;
import com.codi.bus.core.service.*;
import com.codi.bus.core.vo.OpenAccountVo;
import com.codi.bus.core.vo.UserProfileVo;
import com.codi.bus.exception.BaseException;
import com.codi.goldlife.external.IntegralServiceApi;
import com.codi.goldlife.external.databean.ResultBean;
import com.codi.message.util.MessageUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

/**
 * @Author: zengxl
 * @Description: 全局相关控制类
 * @Date: 2018/3/8 13:47
 */
@RestController
@Slf4j
@RequestMapping("h5/pub")
public class H5PubController {
    @Autowired
    private BankLimitService bankLimitService;
    @Autowired
    private AccountValidation accountValidation;
    @Resource(name = "userService")
    private UserService userService;
    @Autowired
    private PaperInfoService paperInfoService;
    @Autowired
    private ClientService clientService;
    @Autowired
    private IntegralServiceApi integralServiceApi;
    @Resource(name = "bankService")
    private BankService bankService;
    @Autowired
    private RedisTemplate<String, String> stringRedisTemplate;
    @Autowired
    private SMSSimpleService smsSimpleService;
    /**
     * @Author zengxl
     * @Description: 全局--限额说明
     * @Date: 2018/3/9 10:47
     */
    @GetMapping("quotas")
    @Loggable
    public BaseResult quotas() {
        return BaseResult.success(bankLimitService.selectAllByState());
    }

    /**
     * 全局--开户--获取验证码
     *
     * @param entity
     * @param bankEntity
     * @param isOpen
     * @param request
     * @return
     */
    @PostMapping("pay-sign-one")
    @Loggable
    public PaySignResult paySignOne(User entity, UserBank bankEntity, @RequestParam boolean isOpen, HttpServletRequest request) {
        bankEntity.setCapitalMode(GlobalConstant.CAPITAL_MODE_EPAY);
        PaySignResult result = accountValidation.validatePaySign(entity, bankEntity, isOpen);
        if (result != null) {
            return result;
        }
        String userId = RequestUtils.getHeader(request, "userid");
        entity.setUserCard(entity.getUserCard().toUpperCase());
        entity.setUserId(Long.valueOf(userId));
        bankEntity.setUserId(entity.getUserId());
        bankEntity.setUserBankOwner(entity.getUserName());
        result = userService.paySign_Step_One(entity, bankEntity);
        if (result.getSuccess() == false && StringUtil.isEmpty(result.getErrorMessage())) {
            result.setErrorMessage(MessageUtil.getErrorMessage(result.getErrorCode(), null));
        }
        return result;
    }

    @GetMapping("getPayBankList")
    @Loggable
    public PayableBankListResult getPayBankList() {
        PayableBankListResult result = null;
        String capitalMode = GlobalConstant.CAPITAL_MODE_EPAY;
        result = bankService.getPayBanks(capitalMode);
        if (result.getSuccess() == false && StringUtil.isEmpty(result.getErrorMessage())) {
            result.setErrorMessage(MessageUtil.getErrorMessage(result.getErrorCode(), null));
        }
        return result;
    }

    /**
     * 全局--开户--添加开户信息
     *
     * @param openAccountVo 开户信息
     * @param userProfileVo 用户属性信息
     * @param request
     * @return
     */
    @PostMapping("openAccountByH5")
    @Loggable
    public com.codi.bus.core.resultModel.BaseResult openAccountByH5(OpenAccountVo openAccountVo, UserProfileVo userProfileVo, HttpServletRequest request) {
        AccountOpenResult result = null;

        Long userId = Long.valueOf(RequestUtils.getHeader(request, "userid"));
        // 用户基本信息
        User entity = new User();
        entity.setUserId(userId);
        entity.setUserName(openAccountVo.getUserName());
        entity.setUserCard(openAccountVo.getUserCard());
        entity.setTradePassword(openAccountVo.getTradePassword());

        // 银行卡信息
        UserBank bankEntity = new UserBank();
        bankEntity.setBankCode(openAccountVo.getBankCode());
        bankEntity.setBankName(openAccountVo.getBankName());
        bankEntity.setUserBankNo(openAccountVo.getUserBankNo());
        bankEntity.setBranchbank(openAccountVo.getVcBranchbank());
        bankEntity.setBankBranchName(openAccountVo.getVcBankname());
        bankEntity.setUserBankMobile(openAccountVo.getUserBankMobile());
        bankEntity.setUserId(userId);
        bankEntity.setUserBankOwner(openAccountVo.getUserName());
        bankEntity.setCapitalMode(GlobalConstant.CAPITAL_MODE_EPAY);
        PaySignResult payResult = accountValidation.validatePayOpenNew(entity, userProfileVo, bankEntity, openAccountVo.getOriginalSerialNo(), openAccountVo.getSmsSerialNo(), openAccountVo.getMobileCode(), openAccountVo.isOpenAcc());
        if (payResult != null) {
            return payResult;
        }
        //验证支行信息
        com.codi.bus.core.resultModel.BaseResult baseResult = accountValidation.validateBranch(bankEntity.getBranchbank());
        if (baseResult != null) {
            return baseResult;
        }
        entity.setUserCard(entity.getUserCard().toUpperCase());
        payResult = userService.paySign_Step_Two(entity, bankEntity, openAccountVo.getOriginalSerialNo(), openAccountVo.getSmsSerialNo(), openAccountVo.getMobileCode());
        if (payResult.getSuccess() == false) {
            if (StringUtil.isEmpty(payResult.getErrorMessage())) {
                payResult.setErrorMessage(MessageUtil.getErrorMessage(payResult.getErrorCode(), null));
            }
            return payResult;
        }
        // 是否是开户
        if (openAccountVo.isOpenAcc()) {
            // Step 2: 调用开户接口
            // 完成银行卡绑定
            entity.setUserState(User.USER_STATE_BANK);
            bankEntity.setExternalProtocolNo(payResult.getProtocolNo());
            result = userService.openAccountNew(entity, userProfileVo, bankEntity);
            if (result.getSuccess() == false) {
                if (StringUtil.isEmpty(result.getErrorMessage())) {
                    result.setErrorMessage(MessageUtil.getErrorMessage(result.getErrorCode(), null));
                }
                return result;
            }

            // 有移动端触发调用
            // Step 3: 调用设置默认风险等级接口
            paperInfoService.addDefaultTestResult(userId, null);

            //查询用户风险等级等资料，app端要缓存 shi.pengyan
            clientService.initClientInfo(userId, result.getUser());

        } else {

            // Step 2: 调用新增交易账号
            // 完成银行卡绑定
            result = userService.addAccount(userId, openAccountVo.getUserCard(), openAccountVo.getTradePassword(), openAccountVo.getUserName(), openAccountVo.getBankCode(), openAccountVo.getUserBankNo(), openAccountVo.getBankName(),
                openAccountVo.getUserBankMobile(), GlobalConstant.CAPITAL_MODE_EPAY, payResult.getProtocolNo(), bankEntity.getBranchbank(), bankEntity.getBankBranchName());
            if (result.getSuccess() == false) {
                if (StringUtil.isEmpty(result.getErrorMessage())) {
                    result.setErrorMessage(MessageUtil.getErrorMessage(result.getErrorCode(), null));
                }
                return result;
            }
        }
        User user = userService.getUser(userId);
        integralServiceApi.sendUserMsg(userId.toString(), user.getUserMobile(), user.getUserName(), GlobalConstant.INTEGRAL_CHANNEL_ID);
        ResultBean resultBean = integralServiceApi.execIntegral(userId.toString(), GlobalConstant.INTEGRAL_CHANNEL_ID, GlobalConstant.INTEGRAL_BUSINESSID_BIND, user.getUserMobile());
        if (resultBean.isSuccess()) {
            log.info("H5--用户绑卡积分添加成功,用户ID={},电话={}", user.getUserId(), user.getUserMobile());
            if (user.getUserInviter() != null) {
                User inviter = userService.getUser(user.getUserInviter());
                ResultBean resultBean1 = integralServiceApi.execIntegral(user.getUserInviter().toString(), GlobalConstant.INTEGRAL_CHANNEL_ID, GlobalConstant.INTEGRAL_BUSINESSID_INVITE_BIND, inviter.getUserMobile());
                if (resultBean1.isSuccess()) {
                    log.info("H5--用户绑卡积分添加成功后，邀请用户开户积分添加成功：邀请人ID={},电话={}", user.getUserInviter(), inviter.getUserMobile());
                } else {
                    log.error("H5--用户绑卡积分添加成功后,邀请用户开户积分添加失败：邀请人ID={},电话={}", user.getUserInviter(), inviter.getUserMobile());
                }
            }
        } else {
            log.error("H5--用户绑卡积分添加失败,用户ID={},电话={}", user.getUserId(), user.getUserMobile());
        }
        return result;
    }

    /**
     * 全局--通过银行卡号获取银行名称
     *
     * @param request
     * @param response
     * @param cardNo
     * @throws BaseException
     * @author mifj
     */
    @GetMapping("/getAccountBank")
    @Loggable
    public void getAccountBank(HttpServletRequest request, HttpServletResponse response, @RequestParam String cardNo) throws BaseException {
        CardBinResult result = accountValidation.validateCard(cardNo);
        if (result != null) {
            ResponseUtils.renderJson(request, response, result, true);
            return;
        }
        result = userService.validateCardInfo(cardNo);
        if (!result.getSuccess() && StringUtil.isEmpty(result.getErrorMessage())) {
            result.setErrorMessage(MessageUtil.getErrorMessage(result.getErrorCode(), null));
        }
        ResponseUtils.renderJson(request, response, result, true);
    }

    /**
     * 发送验证码接口
     * @param request
     * @param response
     * @param phone
     * @param verCodeType
     * @throws BaseException
     */
    @GetMapping("/getVerCode")
    @Loggable
    public void getVerCode(HttpServletRequest request, HttpServletResponse response, @RequestParam String phone, @RequestParam String verCodeType) throws BaseException {
        com.codi.bus.core.resultModel.BaseResult result = new com.codi.bus.core.resultModel.BaseResult();
        if (StringUtils.isEmpty(phone)) {
            log.warn("获取验证码时，手机号码不能为空");
            result.setSuccess(false);
            result.setErrorMessage("手机号码不能为空");
            ResponseUtils.renderJson(request, response, result, true);
            return;
        }
        if (StringUtils.isEmpty(verCodeType)) {
            log.warn("获取验证码时，业务类型不能为空");
            result.setSuccess(false);
            result.setErrorMessage("业务类型不能为空");
            ResponseUtils.renderJson(request, response, result, true);
        }
        if (!StringUtil.isNumeric(phone)) {
            log.warn("获取验证码时，手机号码格式错误");
            result.setSuccess(false);
            result.setErrorMessage("手机号码格式错误");
            ResponseUtils.renderJson(request, response, result, true);
            return;
        }
        boolean flag = userService.checkMobile(phone);
        if("1".equals(verCodeType)){
            //注册,判断手机号是否存在
            if(flag){
                log.warn("手机号码已经存在");
                result.setSuccess(false);
                result.setErrorMessage("手机号码已经存在");
                ResponseUtils.renderJson(request, response, result, true);
                return;
            }
        }else if("2".equals(verCodeType)){
            //忘记密码
            if(!flag){
                log.warn("手机号码不存在");
                result.setSuccess(false);
                result.setErrorMessage("手机号码不存在");
                ResponseUtils.renderJson(request, response, result, true);
                return;
            }
        }
        String verifyCode = RandomUtil.getNumRandom(6, true);
        // 限制在开发环境中使用
        Boolean mockSmsVerifyCode = ConfigurationMgr.getInstance().getBoolean(GlobalConstant.CONFIG_MOCK_SMS_VERIFY_CODE, false);
        if (mockSmsVerifyCode) {
            verifyCode = "666666";
        }
        smsSimpleService.sendMessage(phone,"【科地基金】您好，您的验证码是:"+verifyCode,verCodeType);
        stringRedisTemplate.opsForValue().set("fund_h5_sms_"+verCodeType+"_" + phone, verifyCode, 3, TimeUnit.MINUTES);
        result.setSuccess(true);
        ResponseUtils.renderJson(request, response, result, true);
        return;
    }
}
